import { createDesigner } from '@designable/core';
import {
  ComponentTreeWidget,
  CompositePanel,
  Designer,
  DesignerToolsWidget,
  ResourceWidget,
  SettingsPanel,
  StudioPanel,
  ToolbarPanel,
  ViewPanel,
  ViewportPanel,
  ViewToolsWidget,
  Workspace,
  WorkspacePanel,
} from '@designable/react';
import { SettingsForm } from '@designable/react-settings-form';
import { GForm, GIcon, GModalButton, useRequest } from 'geminis-react';
import { useMemo, useRef, useState } from 'react';
import { Preview } from '@/pages/everydata/form/components/preview/preview';
import './edit.less';
import {
  collectionWidget,
  dataSchema,
  displayWidget,
  inputWidget,
  layoutWidget,
  transformSchema,
  transformTreeNode,
  treeWidget,
} from '@/pages/everydata/form/utils/utils';
import { message } from 'antd';

export const FormEdit = (props: {
  text: string;
  icon: string;
  disabled?: boolean;
  formId?: string;
  categoryId: string;
  onSaved: () => void;
}) => {
  const engine = useMemo(
    () =>
      createDesigner({
        rootComponentName: 'Form',
      }),
    [],
  );
  const dataFormRef = useRef<any>();
  const [data, setData] = useState<any>();

  const submit = (dataFormValue: any, resolve: any, reject: any) => {
    const formData = { ...dataFormValue };
    formData.schemaData = transformSchema(engine.getCurrentTree());
    formData.schemaData.data = dataFormValue.schemaData.data;
    if (formData.schemaData.data.urlType === 'gemini') {
      formData.schemaData.data.url =
        '/api/everydata/data/' + formData.schemaData.data.urlKey + '/{id}';
    }
    delete formData.schemaData.data.urlType;
    delete formData.schemaData.data.urlKey;
    formData.category = { id: props.categoryId };
    useRequest({
      method: 'put',
      url: '/api/everydata/forms',
      data: formData,
      errMsg: '提交数据失败',
    })
      .then((resp) => {
        props.onSaved?.();
        message.success('保存成功');
        resolve(resp);
      })
      .catch((err) => {
        reject(err);
      });
  };

  const save = (): Promise<any> => {
    return new Promise<any>((resolve, reject) => {
      if (dataFormRef.current) {
        const dataForm = dataFormRef.current.getForm();
        dataForm
          .validate()
          .then(() => {
            submit(dataForm.values, resolve, reject);
          })
          .catch((err: any) => {
            reject(err);
          });
      } else {
        submit(data, resolve, reject);
      }
    });
  };

  const onDataFormRefChanged = (el: any) => {
    if (dataFormRef.current) {
      setData(dataFormRef.current.getForm().values);
    }
    dataFormRef.current = el;
    if (el) {
      if (props.formId) {
        if (data) {
          dataFormRef.current.getForm().setInitialValues(data);
        } else {
          const queryParameter = {
            pageSize: 1,
            pageIndex: 0,
            filterGroup: {
              filters: [
                {
                  field: 'id',
                  compareType: '=',
                  value: props.formId,
                },
              ],
            },
          };

          useRequest({
            method: 'post',
            url: '/api/everydata/forms',
            data: queryParameter,
            errMsg: '获取数据错误',
          }).then((resp: any) => {
            let data = resp.content[0];
            setData(data);
            const url = data.schemaData.data.url;
            data.schemaData.data.urlType =
              url.indexOf('/api/everydata/data/') === 0 ? 'gemini' : 'other';
            if (data.schemaData.data.urlType === 'gemini') {
              const end = url.indexOf('/', 20);
              data.schemaData.data.urlKey = data.schemaData.data.url.substring(
                20,
                end,
              );
            }
            dataFormRef.current.getForm().setInitialValues(data);
            engine.setCurrentTree(transformTreeNode(data.schemaData));
          });
        }
      }
    }
  };

  return (
    <GModalButton
      text={props.text}
      button={{
        icon: <GIcon type={props.icon} />,
        disabled: props.disabled === true,
        onClick: () => setData(null),
      }}
      modal={{
        width: '90vw',
        bodyStyle: {
          overflow: 'auto',
          height: '70vh',
          padding: 0,
        },
      }}
      onOk={save}
    >
      <Designer engine={engine}>
        <StudioPanel>
          <CompositePanel>
            <CompositePanel.Item title="数据" icon="Outline">
              <div className="form-data">
                <GForm ref={onDataFormRefChanged} schema={dataSchema} />
              </div>
            </CompositePanel.Item>
            <CompositePanel.Item title="组件" icon="Component">
              <ResourceWidget title="输入" sources={inputWidget} />
              <ResourceWidget title="布局" sources={layoutWidget} />
              <ResourceWidget title="集合" sources={collectionWidget} />
              <ResourceWidget title="显示" sources={displayWidget} />
            </CompositePanel.Item>
          </CompositePanel>
          <Workspace id="form">
            <WorkspacePanel>
              <ToolbarPanel>
                <DesignerToolsWidget />
                <ViewToolsWidget use={['DESIGNABLE', 'PREVIEW']} />
              </ToolbarPanel>
              <ViewportPanel>
                <ViewPanel type="DESIGNABLE">
                  {() => <ComponentTreeWidget components={treeWidget} />}
                </ViewPanel>
                <ViewPanel type="PREVIEW">
                  {(tree) => <Preview tree={tree} />}
                </ViewPanel>
              </ViewportPanel>
            </WorkspacePanel>
          </Workspace>
          <SettingsPanel title="属性设置">
            <SettingsForm />
          </SettingsPanel>
        </StudioPanel>
      </Designer>
    </GModalButton>
  );
};
